# 用到的函数

import json
import logging
import threading
import zipfile

from Config import config
from Local_files import local_files


class func:
    # 线程配置
    threading_manager = threading.Semaphore(value=config.max_threading_count)

    def get_java_info(self: int):
        java_list = local_files.java_versions_list(0)
        return java_list

    def get_version_info(self: int, game_version: str):
        """
        返回详细版本信息的函数。
        :param game_version: 目标版本的自定义名称
        :return: 如果版本存在，返回的元组中依次包括[0]游戏版本号、[1].minecraft文件夹路径、[2]该版本JSON文件路径、[3]版本natives库文件夹应在的路径、[4]版本libraries文件夹路径、[5]minecraft本体客户端路径，[6][7]以及两项启动参数；如果版本不存在，返回None
        """
        game_versions_list = local_files.game_versions_list(0)
        for i in game_versions_list:
            if str(game_version) == i['name']:
                game_version_num: str = str(i['version'])
                version_file_path = config.self_path + r"\.minecraft"
                version_json_path = version_file_path + r"\versions" + "\\" + game_version + "\\" + game_version + ".json"
                libraries_path_1 = version_file_path + r"\versions" + "\\" + game_version + "\\" + game_version + "-natives"
                libraries_path_2 = version_file_path + r"\libraries" + "\\"
                minecraft_jar_path = version_file_path + r"\versions" + "\\" + game_version + "\\" + game_version + ".jar"
                Djava_library_path = r"-Djava.library.path=" + libraries_path_1
                Dminecraft_client_jar = r"-Dminecraft.client.jar=" + minecraft_jar_path
                assetsindex_path_part = version_file_path + "\\assets\\indexes"
                return (game_version_num, version_file_path, version_json_path,
                        libraries_path_1, libraries_path_2, minecraft_jar_path,
                        Djava_library_path, Dminecraft_client_jar, assetsindex_path_part)
        return None

    def zip_natives(self: int, natives_file: dict, libraries_path: str, natives_path: str):
        file_temp_1 = natives_file['classifiers']
        if "natives-windows-64" in file_temp_1:
            file_temp_2: dict = dict(file_temp_1['natives-windows-64'])
        elif "natives-windows" in file_temp_1:
            file_temp_2: dict = dict(file_temp_1['natives-windows'])
        else:
            return None
        file_temp_3: str = str(file_temp_2['path'])
        file_temp_4 = list(file_temp_3.split("/"))
        dividing_str_1 = "\\"
        file_temp_5 = dividing_str_1.join(file_temp_4)
        real_path = libraries_path + file_temp_5
        with zipfile.ZipFile(file=real_path) as natives_temp:
            natives_temp.extractall(path=natives_path)
        return None


class using:
    def java_setting(self: int, java_setting_info: list):
        """

        :param java_setting_info: 该版本的相关信息组成的列表，需要：[0]最大内存，[1]最小内存，[2]Djava参数（natives），[3]Dminecraft参数
        :return: 包含该.jar文件和其他有关参数的，可直接拼接成脚本使用的代码片段
        """
        info_max_memory = java_setting_info[0]
        info_min_memory = java_setting_info[1]
        Djava_library_path = java_setting_info[2]
        Dminecraft_jar_path = java_setting_info[3]
        output_java_setting = info_max_memory + " " + info_min_memory + " " \
                              + Djava_library_path + " " \
                              + Dminecraft_jar_path
        return output_java_setting

    def get_libraries_json(self: int, game_version_info: list):
        """
        返回拼接成的“-cp”+普通库1+普通库2+……
        :param game_version_info: 该版本的相关信息组成的列表，需要：[0]版本名称，[1]版本JSON路径，[2]版本libraries路径，[3]版本游戏本体路径，[4]版本natives文件路径
        :return 从该JSON文件中提取出的，可直接拼接成脚本使用的代码片段
        """
        output_path = []
        game_version_name = game_version_info[0]
        game_version_json_path = game_version_info[1]
        libraries_path = game_version_info[2]
        minecraft_jar_path = game_version_info[3]
        natives_path = game_version_info[4]
        with open(file=game_version_json_path) as json_file:
            json_data = json.load(json_file)
            info_back_type_list = json_data['libraries']
            for i in info_back_type_list:
                if "rules" in i:
                    data_temp_1 = list(i['rules'])
                    if len(data_temp_1) == 1:
                        allowing_list = list(dict(dict(data_temp_1[0])["os"])['name'])
                        if not "windows" in allowing_list:
                            continue
                    if len(data_temp_1) == 2:
                        disallowing_list = list(dict(dict(data_temp_1[1])['os'])['name'])
                        if "windows" in disallowing_list:
                            continue

                data_temp_2 = dict(i['downloads'])
                if "classifiers" in data_temp_2:
                    func.zip_natives(0, data_temp_2, libraries_path, natives_path)
                    continue
                elif not 'artifact' in data_temp_2:
                    continue
                else:
                    data_temp_2_ = dict(data_temp_2['artifact'])
                data_temp_3 = str(data_temp_2_['path'])
                data_temp_4 = list(data_temp_3.split("/"))
                dividing_str_1 = "\\"
                data_temp_5 = dividing_str_1.join(data_temp_4)
                real_path = libraries_path + data_temp_5
                if not real_path in output_path:
                    output_path.append(real_path)
            output_path.append(minecraft_jar_path)
            dividing_str_2 = ";"
            output_path_str = dividing_str_2.join(output_path)
        return output_path_str

    def get_player_info(self: int, get_player_info: list):
        """
        此函数可以生成启动脚本中的Minecraft参数。
        :param get_player_info: 需要输入一个列表，内容分别为：[0]版本JSON文件路径，[1]玩家名，[2]玩家UUID，[3].minecraft文件夹路径，[4]assets文件夹路径
        :return: 从该JSON文件中提取出的，以及输入的信息组成的，可直接拼接成脚本使用的代码片段
        """
        info_version_json_path = get_player_info[0]
        info_player_name = get_player_info[1]
        info_player_uuid = get_player_info[2]
        info_minecraft_jar_path = get_player_info[3]
        info_assets_path = get_player_info[4]

        with open(file=info_version_json_path) as json_file:
            json_data = json.load(json_file)
            main_class = json_data['mainClass']
            if "minecraftArguments" in json_data:
                minecraft_arguments_ = str(json_data['minecraftArguments'])
                assets_index_name = str(dict(json_data['assetIndex'])['id'])
                version_type = str(json_data['type'])
                minecraft_arguments = minecraft_arguments_.replace("${auth_player_name}", info_player_name) \
                    .replace("${version_name}", "FanCraftLauncher") \
                    .replace("${game_directory}", info_minecraft_jar_path) \
                    .replace("${assets_root}", info_assets_path) \
                    .replace("${assets_index_name}", assets_index_name) \
                    .replace("${auth_uuid}", info_player_uuid) \
                    .replace("${auth_access_token}", info_player_uuid) \
                    .replace("${user_properties}", "{}") \
                    .replace("${auth_xuid}", "{}") \
                    .replace("${clientid}", "{}") \
                    .replace("${user_type}", "legacy") \
                    .replace("${version_type}", version_type)
            elif "arguments" in json_data:
                temp_list = []
                minecraft_arguments__ = list(json_data["arguments"]["game"])
                assets_index_name = str(dict(json_data['assetIndex'])['id'])
                version_type = str(json_data['type'])
                for i in minecraft_arguments__:
                    if type(i) == str:
                        temp_list.append(i)
                minecraft_arguments_ = " ".join(temp_list)
                minecraft_arguments = minecraft_arguments_.replace("${auth_player_name}", info_player_name) \
                    .replace("${version_name}", "FanCraftLauncher") \
                    .replace("${game_directory}", info_minecraft_jar_path) \
                    .replace("${assets_root}", info_assets_path) \
                    .replace("${assets_index_name}", assets_index_name) \
                    .replace("${auth_uuid}", info_player_uuid) \
                    .replace("${auth_access_token}", info_player_uuid) \
                    .replace("${user_properties}", "{}") \
                    .replace("${auth_xuid}", "{}") \
                    .replace("${clientid}", "{}") \
                    .replace("${user_type}", "legacy") \
                    .replace("${version_type}", version_type)
            output_player_info = main_class + " " + minecraft_arguments
        return output_player_info

